/** @type {HTMLCanvasElement} */

import { randomColor, randomNum } from '../util/index.js'

import Stats from '../node_modules/stats.js/src/Stats.js'

const canvas = document.querySelector('#canvas')
const width = window.innerWidth
const height = window.innerHeight
canvas.width = width
canvas.height = height
const c = canvas.getContext('2d')

const options = {
    particleNum: 100,
    rMin: 10,
    rMax: 400,
    rParticle: 2,
    showCircle: false,
    vCentripetal: 0.003,//向心力速度,改变这个值(0.0001--500000)会有不同效果,没发解释,这就是魔法
    xFun: 'sin',
    yFun: 'cos'
}

//stats
const stats = new Stats()
stats.showPanel(0)
document.body.appendChild(stats.dom)

//gui
const gui = new dat.GUI({ width: 320 });
const folder1 = gui.addFolder('基础')
folder1.open()
const folder2 = gui.addFolder('魔法')
folder2.open()


const controller1 = folder1.add(options, 'particleNum', 20, 1200, 1)
const controller2 = folder1.add(options, 'rMin', 0, 10, 1)
const controller3 = folder1.add(options, 'rMax', 10, 800, 1)
const controller4 = folder1.add(options, 'rParticle', 1, 20, 1)
const controller5 = folder1.add(options, 'showCircle', [false, true])
const controller6 = folder2.add(options, 'vCentripetal')
const controller7 = folder2.add(options, 'xFun', ['sin', 'cos', 'tan'])
const controller8 = folder2.add(options, 'yFun', ['sin', 'cos', 'tan'])

controller1.onFinishChange(() => {
    init()
})
controller2.onFinishChange(() => {
    init()
})
controller3.onFinishChange(() => {
    init()
})
controller4.onFinishChange(() => {
    init()
})

// controller5.onFinishChange(() => {
//     init()
// })

controller6.onFinishChange(() => {
    init()
})

class Particle {
    constructor(rCircle, color) {
        //中心点坐标
        this.centerX = width / 2
        this.centerY = height / 2
        //粒子坐标
        this.x = this.centerX
        this.y = this.centerY
        //环绕半径
        this.rCircle = rCircle
        //粒子半径
        this.rParticle = options.rParticle
        this.color = color
        // 上一个点,用来画拖尾
        this.lastX = this.x
        this.lastY = this.y

        //旋转
        this.angle = 2 * Math.PI * Math.random()
        //向心力速度
        this.v = options.vCentripetal
    }

    //头部,其实也可以不画
    drawCircle() {
        c.beginPath()
        c.arc(this.x, this.y, this.rParticle, 0, Math.PI * 2, false)
        c.fillStyle = this.color
        c.fill()
    }

    //拖尾
    drawTail() {
        c.beginPath()
        c.lineWidth = this.rParticle
        c.moveTo(this.lastX, this.lastY)
        c.lineTo(this.x, this.y)
        c.strokeStyle = this.color
        c.stroke()
    }

    update() {
        this.angle += this.v
        this.lastX = this.x
        this.lastY = this.y

        //设置不同的三角函数,会有不同的效果,this is magic
        this.x = this.centerX + this.rCircle * whichFun(options.xFun)(this.angle)
        this.y = this.centerY + this.rCircle * whichFun(options.yFun)(this.angle)
        if (options.showCircle) {
            this.drawCircle()
        }
        this.drawTail()
    }
}

const particleArr = []

function whichFun(funType) {
    const sin = (angle) => Math.sin(angle)
    const cos = (angle) => Math.cos(angle)
    const tan = (angle) => Math.tan(angle)
    if (funType === 'sin') return sin
    if (funType === 'cos') return cos
    if (funType === 'tan') return tan
}

function animate() {
    stats.begin()

    c.fillStyle = 'rgba(0,0,0,0.1)'
    c.fillRect(0, 0, width, height)
    particleArr.forEach(p => {
        p.update()
    })

    stats.end()
    window.requestAnimationFrame(animate)
}

function init() {
    particleArr.length = 0
    c.clearRect(0, 0, width, height)
    for (let i = 0; i < options.particleNum; i++) {
        const c = randomColor()
        const rCircel = randomNum(options.rMin, options.rMax)
        const p = new Particle(rCircel, c)
        particleArr.push(p)
    }
}

init()
animate()